package com.bsj.travel.system.authorization.interceptor;

import com.alibaba.fastjson.JSON;
import com.bsj.travel.cached.redis.RedisCached;
import com.bsj.travel.constant.Constants;
import com.bsj.travel.constant.NumericalConstants;
import com.bsj.travel.def.annotation.AdminControl;
import com.bsj.travel.def.annotation.AdminClear;
import com.bsj.travel.def.global.JsonResult;
import com.bsj.travel.def.global.JsonResultEnum;
import com.bsj.travel.def.common.VO.TokenUser;
import com.bsj.travel.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/***
 * @description AdminControlInterceptor
 * @author LiJiaXin
 * @version 1.0.0
 * @time 2024/1/10 16:37
 **/
@Component
@Slf4j
public class AdminControlInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisCached redisCached;

    /**
     * @desc 拦截请求，处理
     * @author
     **/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 判断请求的Controller类或方法是否有注解
        boolean authorizationMethod = method.getAnnotation(AdminControl.class) != null;
        boolean clearMethod = method.getAnnotation(AdminClear.class) != null;
        //判断类上有没有这个注解
        boolean authorizationClazz = handlerMethod.getBeanType().getAnnotation(
                AdminControl.class) != null;

        if (!(authorizationMethod || authorizationClazz) || clearMethod) {
            return true;
        }

        //校验是否为超级管理员
        String token = SecurityUtils.getToken(request);
        if (StringUtils.isNotBlank(token)) {
            TokenUser tokenUser = redisCached.get(Constants.LOGIN_TOKEN_KEY + token, TokenUser.class);
            if (null != tokenUser && tokenUser.getSystemUser().getParentId().equals(NumericalConstants.NEGATIVE_ONE)) {
                return true;
            }
        }
        //返回授权错误码给前端
        response.setStatus(401);
        //这句话的意思，是让浏览器用utf8来解析返回的数据
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        //这句话的意思，是告诉servlet用UTF-8转码，而不是用默认的ISO8859
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.print(JSON.toJSONString(JsonResult.fail(JsonResultEnum.NOT_AUTH)));
        out.flush();
        return false;
    }

}
